package com.css.fxfzfxqh.modules.singleIndicatorRiskZoneSet.service;

import cn.hutool.core.util.IdUtil;
import com.css.fxfzfxqh.modules.buildingKilometerGrid.exceptions.BizException;
import com.css.fxfzfxqh.modules.singleIndicatorRiskZoneSet.model.entity.FxqhSingleIndicatorRiskZoneSet;
import com.css.fxfzfxqh.modules.singleIndicatorRiskZoneSet.model.param.SingleIndicatorRiskZoneSetSaveParam;
import com.css.fxfzfxqh.modules.singleIndicatorRiskZoneSet.model.vo.SingleIndicatorRiskZoneSetSaveVo;
import com.css.fxfzfxqh.modules.singleIndicatorRiskZoneSet.repository.SingleIndicatorRiskZoneSetRepository;
import com.css.fxfzfxqh.util.PlatformDateUtils;
import com.css.fxfzfxqh.web.PlatformSessionContext;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.ValueOperations;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.Date;
import java.util.concurrent.TimeUnit;

@Slf4j
@Service
@Transactional(rollbackFor = Exception.class)
public class SingleIndicatorRiskZoneSetService {
    @Autowired
    private SingleIndicatorRiskZoneSetRepository singleIndicatorRiskZoneSetRepository;
    @Autowired
    private RedisTemplate redisTemplate;
    // 临界值缓存
    private static final String VALUE_CACHE = "singleIndicatorRiskZoneSet:";

    public void save(SingleIndicatorRiskZoneSetSaveParam param) throws BizException {
        saveParamCheck(param);
        if (param.getType() == 1) {
            FxqhSingleIndicatorRiskZoneSet fxqhSingleIndicatorRiskZoneSet = new FxqhSingleIndicatorRiskZoneSet();
            fxqhSingleIndicatorRiskZoneSet.setType(1);
            fxqhSingleIndicatorRiskZoneSet.setV1(param.getV1());
            fxqhSingleIndicatorRiskZoneSet.setV2(param.getV2());
            fxqhSingleIndicatorRiskZoneSet.setV3(param.getV3());
            fxqhSingleIndicatorRiskZoneSet.setV4(param.getV4());
            this.saveHandle(fxqhSingleIndicatorRiskZoneSet);
        }
        if (param.getType() == 2) {
            FxqhSingleIndicatorRiskZoneSet fxqhSingleIndicatorRiskZoneSet = new FxqhSingleIndicatorRiskZoneSet();
            fxqhSingleIndicatorRiskZoneSet.setType(2);
            fxqhSingleIndicatorRiskZoneSet.setV1(param.getV1());
            fxqhSingleIndicatorRiskZoneSet.setV2(param.getV2());
            fxqhSingleIndicatorRiskZoneSet.setV3(param.getV3());
            fxqhSingleIndicatorRiskZoneSet.setV4(param.getV4());
            this.saveHandle(fxqhSingleIndicatorRiskZoneSet);
            FxqhSingleIndicatorRiskZoneSet fxqhSingleIndicatorRiskZoneSetXqx = new FxqhSingleIndicatorRiskZoneSet();
            fxqhSingleIndicatorRiskZoneSetXqx.setType(3);
            fxqhSingleIndicatorRiskZoneSetXqx.setV1(param.getXqxV1());
            fxqhSingleIndicatorRiskZoneSetXqx.setV2(param.getXqxV2());
            fxqhSingleIndicatorRiskZoneSetXqx.setV3(param.getXqxV3());
            fxqhSingleIndicatorRiskZoneSetXqx.setV4(param.getXqxV4());
            this.saveHandle(fxqhSingleIndicatorRiskZoneSetXqx);
        }
        if (param.getType() == 3) {
            FxqhSingleIndicatorRiskZoneSet fxqhSingleIndicatorRiskZoneSet = new FxqhSingleIndicatorRiskZoneSet();
            fxqhSingleIndicatorRiskZoneSet.setType(4);
            fxqhSingleIndicatorRiskZoneSet.setV1(param.getV1());
            fxqhSingleIndicatorRiskZoneSet.setV2(param.getV2());
            fxqhSingleIndicatorRiskZoneSet.setV3(param.getV3());
            fxqhSingleIndicatorRiskZoneSet.setV4(param.getV4());
            this.saveHandle(fxqhSingleIndicatorRiskZoneSet);
            FxqhSingleIndicatorRiskZoneSet fxqhSingleIndicatorRiskZoneSetXqx = new FxqhSingleIndicatorRiskZoneSet();
            fxqhSingleIndicatorRiskZoneSetXqx.setType(5);
            fxqhSingleIndicatorRiskZoneSetXqx.setV1(param.getXqxV1());
            fxqhSingleIndicatorRiskZoneSetXqx.setV2(param.getXqxV2());
            fxqhSingleIndicatorRiskZoneSetXqx.setV3(param.getXqxV3());
            fxqhSingleIndicatorRiskZoneSetXqx.setV4(param.getXqxV4());
            this.saveHandle(fxqhSingleIndicatorRiskZoneSetXqx);
        }
    }

    /**
     * 保存
     *
     * @return
     */
    public void saveHandle(FxqhSingleIndicatorRiskZoneSet param) {
        Date currTime = new Date();
        String currUid = PlatformSessionContext.getUserID();
        FxqhSingleIndicatorRiskZoneSet fxqhSingleIndicatorRiskZoneSet = singleIndicatorRiskZoneSetRepository.selectByType(param.getType());
        if (fxqhSingleIndicatorRiskZoneSet == null) {
            // 走新增
            param.setId(IdUtil.getSnowflakeNextIdStr());
            param.setCreateUser(currUid);
            param.setCreateTime(currTime);
            singleIndicatorRiskZoneSetRepository.insert(param);
        } else {
            // 更新
            fxqhSingleIndicatorRiskZoneSet.setUpdateTime(PlatformDateUtils.getCurrentTimestamp());
            fxqhSingleIndicatorRiskZoneSet.setUpdateUser(PlatformSessionContext.getUserID());
            fxqhSingleIndicatorRiskZoneSet.setV1(param.getV1());
            fxqhSingleIndicatorRiskZoneSet.setV2(param.getV2());
            fxqhSingleIndicatorRiskZoneSet.setV3(param.getV3());
            fxqhSingleIndicatorRiskZoneSet.setV4(param.getV4());
            singleIndicatorRiskZoneSetRepository.updateById(fxqhSingleIndicatorRiskZoneSet);
        }
        redisTemplate.delete(VALUE_CACHE + param.getType());
    }

    /**
     * 保存方法，参数检查
     *
     * @param param
     * @throws BizException
     */
    private void saveParamCheck(SingleIndicatorRiskZoneSetSaveParam param) throws BizException {
        if (param.getType() == null) {
            throw new BizException("type不能为空");
        }
        if (param.getType() > 3) {
            throw new BizException("type参数错误");
        }
        if (StringUtils.isBlank(param.getV1())) {
            throw new BizException("临界值1不能为空");
        }
        if (StringUtils.isBlank(param.getV2())) {
            throw new BizException("临界值2不能为空");
        }
        if (StringUtils.isBlank(param.getV3())) {
            throw new BizException("临界值3不能为空");
        }
        if (StringUtils.isBlank(param.getV4())) {
            throw new BizException("临界值4不能为空");
        }
        if (Double.parseDouble(param.getV1()) > Double.parseDouble(param.getV2())) {
            throw new BizException("临界值1不能大于临界值2");
        }
        if (Double.parseDouble(param.getV2()) > Double.parseDouble(param.getV3())) {
            throw new BizException("临界值2不能大于临界值3");
        }
        if (Double.parseDouble(param.getV3()) > Double.parseDouble(param.getV4())) {
            throw new BizException("临界值3不能大于临界值4");
        }
        if (param.getType() != 1) {
            if (StringUtils.isBlank(param.getXqxV1())) {
                throw new BizException("新疆、青海和西藏地区临界值1不能为空");
            }
            if (StringUtils.isBlank(param.getXqxV2())) {
                throw new BizException("新疆、青海和西藏地区临界值2不能为空");
            }
            if (StringUtils.isBlank(param.getXqxV3())) {
                throw new BizException("新疆、青海和西藏地区临界值3不能为空");
            }
            if (StringUtils.isBlank(param.getXqxV4())) {
                throw new BizException("新疆、青海和西藏地区临界值4不能为空");
            }
            if (Double.parseDouble(param.getXqxV1()) > Double.parseDouble(param.getXqxV2())) {
                throw new BizException("新疆、青海和西藏地区临界值1不能大于临界值2");
            }
            if (Double.parseDouble(param.getXqxV2()) > Double.parseDouble(param.getXqxV3())) {
                throw new BizException("新疆、青海和西藏地区临界值2不能大于临界值3");
            }
            if (Double.parseDouble(param.getXqxV3()) > Double.parseDouble(param.getXqxV4())) {
                throw new BizException("新疆、青海和西藏地区临界值3不能大于临界值4");
            }
        }
    }

    public FxqhSingleIndicatorRiskZoneSet selectByType(Integer type) {
        ValueOperations<String, FxqhSingleIndicatorRiskZoneSet> ops = redisTemplate.opsForValue();
        FxqhSingleIndicatorRiskZoneSet fxqhSingleIndicatorRiskZoneSet = ops.get(VALUE_CACHE + type);
        if (fxqhSingleIndicatorRiskZoneSet == null) {
            fxqhSingleIndicatorRiskZoneSet = singleIndicatorRiskZoneSetRepository.selectByType(type);
            if (fxqhSingleIndicatorRiskZoneSet != null) {
                ops.set(VALUE_CACHE + type, fxqhSingleIndicatorRiskZoneSet);
                redisTemplate.expire(VALUE_CACHE + type, 10, TimeUnit.HOURS);
            }
        }
        return fxqhSingleIndicatorRiskZoneSet;
    }

    public SingleIndicatorRiskZoneSetSaveVo get(Integer type) {
        if (type == 1) {
            return fxqhSingleIndicatorRiskZoneSetEntity2Vo(this.selectByType(1), null);
        }
        if (type == 2) {
            return fxqhSingleIndicatorRiskZoneSetEntity2Vo(this.selectByType(2), this.selectByType(3));
        }
        if (type == 3) {
            return fxqhSingleIndicatorRiskZoneSetEntity2Vo(this.selectByType(4), this.selectByType(5));
        }
        return null;
    }

    private static SingleIndicatorRiskZoneSetSaveVo fxqhSingleIndicatorRiskZoneSetEntity2Vo(FxqhSingleIndicatorRiskZoneSet entity, FxqhSingleIndicatorRiskZoneSet xqxEntity) {
        SingleIndicatorRiskZoneSetSaveVo vo = new SingleIndicatorRiskZoneSetSaveVo();
        if (entity == null) {
            vo.setV1("0");
            vo.setV2("0");
            vo.setV3("0");
            vo.setV4("0");
        } else {
            vo.setV1(entity.getV1());
            vo.setV2(entity.getV2());
            vo.setV3(entity.getV3());
            vo.setV4(entity.getV4());
        }
        if (xqxEntity == null) {
            vo.setXqxV1("0");
            vo.setXqxV2("0");
            vo.setXqxV3("0");
            vo.setXqxV4("0");
        } else {
            vo.setXqxV1(xqxEntity.getV1());
            vo.setXqxV2(xqxEntity.getV2());
            vo.setXqxV3(xqxEntity.getV3());
            vo.setXqxV4(xqxEntity.getV4());
        }
        return vo;
    }

    /**
     * 获取区划等级
     * @param value 区划值
     * @param type 分类 1-抗震能力 2-人员伤亡 3-经济损失
     * @return
     */
    public String getLevel(BigDecimal value, Integer type) {
        FxqhSingleIndicatorRiskZoneSet fxqhSingleIndicatorRiskZoneSet = singleIndicatorRiskZoneSetRepository.selectByType(type);
//        if (value.multiply(new BigDecimal(100)).compareTo(new BigDecimal(fxqhSingleIndicatorRiskZoneSet.getV1())) <= 0) {
//            return "I";
//        }
//        if (value.multiply(new BigDecimal(100)).compareTo(new BigDecimal(fxqhSingleIndicatorRiskZoneSet.getV1())) > 0 && value.compareTo(new BigDecimal(fxqhSingleIndicatorRiskZoneSet.getV2())) <= 0) {
//            return "II";
//        }
//        if (value.multiply(new BigDecimal(100)).compareTo(new BigDecimal(fxqhSingleIndicatorRiskZoneSet.getV2())) > 0 && value.compareTo(new BigDecimal(fxqhSingleIndicatorRiskZoneSet.getV3())) <= 0) {
//            return "III";
//        }
//        if (value.multiply(new BigDecimal(100)).compareTo(new BigDecimal(fxqhSingleIndicatorRiskZoneSet.getV3())) > 0 && value.compareTo(new BigDecimal(fxqhSingleIndicatorRiskZoneSet.getV4())) <= 0) {
//            return "IV";
//        }
//        return "V";
        if(2 == type||3 == type){
            if (value.compareTo(new BigDecimal(fxqhSingleIndicatorRiskZoneSet.getV1())) <= 0) {
                return "V";
            }
            if (value.compareTo(new BigDecimal(fxqhSingleIndicatorRiskZoneSet.getV1())) > 0 && value.compareTo(new BigDecimal(fxqhSingleIndicatorRiskZoneSet.getV2())) <= 0) {
                return "IV";
            }
            if (value.compareTo(new BigDecimal(fxqhSingleIndicatorRiskZoneSet.getV2())) > 0 && value.compareTo(new BigDecimal(fxqhSingleIndicatorRiskZoneSet.getV3())) <= 0) {
                return "III";
            }
            if (value.compareTo(new BigDecimal(fxqhSingleIndicatorRiskZoneSet.getV3())) > 0 && value.compareTo(new BigDecimal(fxqhSingleIndicatorRiskZoneSet.getV4())) <= 0) {
                return "II";
            }
        }else{
            if (value.compareTo(new BigDecimal(fxqhSingleIndicatorRiskZoneSet.getV1()).divide(BigDecimal.valueOf(100),2, RoundingMode.HALF_DOWN)) <= 0) {
                return "V";
            }
            if (value.compareTo(new BigDecimal(fxqhSingleIndicatorRiskZoneSet.getV1()).divide(BigDecimal.valueOf(100),2, RoundingMode.HALF_DOWN)) > 0 && value.compareTo(new BigDecimal(fxqhSingleIndicatorRiskZoneSet.getV2()).divide(BigDecimal.valueOf(100),2, RoundingMode.HALF_DOWN)) <= 0) {
                return "IV";
            }
            if (value.compareTo(new BigDecimal(fxqhSingleIndicatorRiskZoneSet.getV2()).divide(BigDecimal.valueOf(100),2, RoundingMode.HALF_DOWN)) > 0 && value.compareTo(new BigDecimal(fxqhSingleIndicatorRiskZoneSet.getV3()).divide(BigDecimal.valueOf(100),2, RoundingMode.HALF_DOWN)) <= 0) {
                return "III";
            }
            if (value.compareTo(new BigDecimal(fxqhSingleIndicatorRiskZoneSet.getV3()).divide(BigDecimal.valueOf(100),2, RoundingMode.HALF_DOWN)) > 0 && value.compareTo(new BigDecimal(fxqhSingleIndicatorRiskZoneSet.getV4()).divide(BigDecimal.valueOf(100),2, RoundingMode.HALF_DOWN)) <= 0) {
                return "II";
            }
        }

        return "I";
    }
}
